package com.codecoord.spring.core;

import com.codecoord.spring.domain.Person;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinitionReader;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.AbstractRefreshableApplicationContext;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import java.util.Set;

/**
 * 基于XML上下文加载测试
 *
 * @author tianxincoord@163.com
 * @since 2022/2/15
 */
@SuppressWarnings("all")
public class XmlApplicationContextTest {
	/**
	 * 基于xml加载
	 * 一、初始化Bean阶段
	 * 实例化：{@link ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(String[], boolean, ApplicationContext)}
	 *	- 设置父类容器
	 *	- 设置配置文件路径
	 *	- 刷新容器即为开启整个容器的加载流程
	 * 刷新容器：{@link AbstractApplicationContext#refresh()}
	 *	- 启动重量级锁：synchronized (this.startupShutdownMonitor)，同一时间只能有个线程下进行初始化
	 * 	- {@link AbstractApplicationContext#obtainFreshBeanFactory()}
	 * 		- {@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
	 * 			- {@link AbstractRefreshableApplicationContext#createBeanFactory()}
	 * 			- {@link AbstractRefreshableApplicationContext#customizeBeanFactory(DefaultListableBeanFactory)}
	 * 			- {@link AbstractXmlApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory)}
	 * 				- {@link AbstractXmlApplicationContext#loadBeanDefinitions(XmlBeanDefinitionReader)}
	 * 					- {@link AbstractBeanDefinitionReader#loadBeanDefinitions(String...)}
	 * 					- {@link AbstractBeanDefinitionReader#loadBeanDefinitions(String)}
	 * 					- {@link AbstractBeanDefinitionReader#loadBeanDefinitions(String, Set)}
	 * 					- {@link AbstractBeanDefinitionReader#loadBeanDefinitions(Resource...)}
	 * 					- {@link XmlBeanDefinitionReader#loadBeanDefinitions(EncodedResource)}
	 * 					- {@link XmlBeanDefinitionReader#doLoadBeanDefinitions(InputSource, Resource)}
	 * 					- 解析Bean信息
	 * 					- {@link DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions(Element)}
	 * 					- {@link DefaultBeanDefinitionDocumentReader#parseDefaultElement(Element, BeanDefinitionParserDelegate)}
	 * 					- {@link DefaultListableBeanFactory#registerBeanDefinition(String, BeanDefinition)}
	 * 					- {@link DefaultBeanDefinitionDocumentReader#processBeanDefinition(Element, BeanDefinitionParserDelegate)}
	 * 					- 注册Bean信息
	 * 					- {@link DefaultListableBeanFactory#registerBeanDefinition(String, BeanDefinition)}
	 */
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
		Person person = context.getBean("person", Person.class);
		System.out.println("person = " + person);
		context.close();
	}
}
